package controller

import (
	"net/http"
	"path"
	"strings"

	"github.com/gin-gonic/gin"
	"khao.fun/shizhan/common"
	"khao.fun/shizhan/dto"
	"khao.fun/shizhan/model"
	"khao.fun/shizhan/response"
	"khao.fun/shizhan/service"
)

// @Summary 上传单个图片
// @Description 上传单个图片
// @Tags upload
// @Produce json
// @Param img formData file true "上传的图片"
// @Param type formData string true "上传的图片类型，avatar或topic"
// @Success 200 {string} string "{"msg": "上传成功","更新数据库时失败",不支持的图片格式","图片尺寸不能大于6Mb"}"
// @Failure 400 {string} string "{"msg": "获取图片失败","储存图片时失败"}"
// @Router /upload/image [post]
func Upload_image(ctx *gin.Context) {
	user := ctx.MustGet("user").(model.User_profile)
	img, err := ctx.FormFile("img")
	if err != nil {
		response.Fail(ctx, 400, err, "获取图片失败")
		return
	}
	if img.Size > 6<<20 {
		response.Success(ctx, nil, "图片尺寸不能大于6Mb")
		return
	}
	ext := path.Ext(img.Filename) //获取文件的后缀名
	if ext != ".png" && ext != ".jpg" && ext != ".jpeg" && ext != ".bmp" && ext != ".gif" {
		response.Success(ctx, nil, "不支持的图片格式")
		return
	}
	dir := common.Mkdir("./upload_Images")                                            //按照日期创建文件夹,放在./upload_Images下
	filePath := strings.Replace(dir, "\\", "/", -1) + "/" + common.RandomName() + ext //创建随机文件名，并加入到新建的文件夹下
	err = ctx.SaveUploadedFile(img, filePath)
	if err != nil {
		response.Fail(ctx, 400, err, "储存图片时失败")
		return
	}
	imgStruct := &model.Image{
		Type:      ctx.PostForm("type"), //avatar或topic
		UserId:    user.User_id,         //上传图片的用户id
		ImagePath: filePath,             //图片储存的地址
	}
	err = service.UploadImage(imgStruct) //更新后，结构体里的id字段会加上对应的值
	if err != nil {
		response.Success(ctx, err, "更新数据库时失败")
		return
	}
	response.Success(ctx, gin.H{
		"imageId":   imgStruct.Id, //返回图片的id
		"imagePath": filePath,     //返回图片的储存路径
	}, "上传成功")
}

// @Summary 删除单个图片
// @Description 根据图片id删除单个图片
// @Tags upload
// @Produce json
// @Param imgId formData string true "删除的图片id"
// @Success 200 {string} string "{"msg": "删除图片成功"}"
// @Failure 400 {string} string "{"msg": "删除图片失败"}"
// @Router /upload/deleteImage [delete]
func Delete_Image(ctx *gin.Context) {
	err := service.DeleteImage(ctx.PostForm("imgId"))
	if err != nil {
		response.Fail(ctx, 400, err, "删除图片失败")
	}
	response.Success(ctx, nil, "删除图片成功")
}

// @Summary 查询用户上传的所有图片
// @Description 查询用户上传的所有图片
// @Tags upload
// @Produce json
// @Param userId query string true "查询的对象id"
// @Success 200 {string} string "{"msg": "获取成功"}"
// @Failure 404 {string} string "{"msg": "图片列表为空"}"
// @Router /upload/imageList [get]
func Image_ListAll(ctx *gin.Context) {
	var res []model.Image
	var res_json []dto.ImageDto
	err := service.Image_ListAll(&res, ctx.Query("userId"))
	if err != nil {
		response.Fail(ctx, 400, err, "获取列表失败")
		return
	}
	for _, v := range res {
		res_json = append(res_json, dto.Dto_image(v))
	}
	if len(res) == 0 {
		response.Fail(ctx, http.StatusNotFound, nil, "图片列表为空")
	} else {
		response.Success(ctx, res_json, "获取成功")
	}
}

// @Summary 上传单个文件
// @Description 上传单个文件
// @Tags upload
// @Produce json
// @Param file formData file true "上传的文件"
// @Success 200 {string} string "{"msg": "上传成功","更新数据库时失败","单个上传文件不能大于100mb"}"
// @Failure 400 {string} string "{"msg": "获取文件失败","储存文件时失败"}"
// @Router /upload/file [post]
func Upload_file(ctx *gin.Context) {
	user := ctx.MustGet("user").(model.User_profile)
	file, err := ctx.FormFile("file")
	if err != nil {
		response.Fail(ctx, 400, err, "获取文件失败")
		return
	}
	if file.Size > 100<<20 {
		response.Success(ctx, nil, "单个上传文件不能大于100mb")
		return
	}
	ext := path.Ext(file.Filename)                                                    //获取文件的后缀名
	dir := common.Mkdir("./upload_Files")                                             //按照日期创建文件夹，放在./upload_Files下
	filePath := strings.Replace(dir, "\\", "/", -1) + "/" + common.RandomName() + ext //创建随机文件名，并加入到新建的文件夹下
	err = ctx.SaveUploadedFile(file, filePath)
	if err != nil {
		response.Fail(ctx, 400, err, "储存文件时失败")
		return
	}
	fileStruct := &model.File{
		UserId:   user.User_id,  //上传文件的用户id
		Filename: file.Filename, //文件原名
		FilePath: filePath,      //文件储存的地址
	}
	err = service.UploadFile(fileStruct)
	if err != nil {
		response.Success(ctx, err, "更新数据库时失败")
		return
	}
	response.Success(ctx, gin.H{
		"fileId":   fileStruct.Id, //返回文件的id
		"filePath": filePath,      //返回图片的储存路径
	}, "上传成功")
}

// @Summary 删除单个文件
// @Description 根据图片id删除单个文件
// @Tags upload
// @Produce json
// @Param fileId formData string true "删除的文件id"
// @Success 200 {string} string "{"msg": "删除文件成功"}"
// @Failure 400 {string} string "{"msg": "删除文件失败"}"
// @Router /upload/deleteFile [delete]
func Delete_File(ctx *gin.Context) {
	err := service.DeleteFile(ctx.PostForm("fileId"))
	if err != nil {
		response.Fail(ctx, 400, err, "删除文件失败")
	}
	response.Success(ctx, nil, "删除文件成功")
}

// @Summary 查询用户上传的所有文件
// @Description 查询用户上传的所有文件
// @Tags upload
// @Produce json
// @Param userId query string true "查询的目标用户id"
// @Success 200 {string} string "{"msg": "获取成功"}"
// @Failure 404 {string} string "{"msg": "文件列表为空"}"
// @Router /upload/fileList [get]
func File_ListAll(ctx *gin.Context) {
	var res []model.File
	var res_json []dto.FileDto
	err := service.File_ListAll(&res, ctx.Query("userId"))
	if err != nil {
		response.Fail(ctx, 400, err, "获取列表失败")
		return
	}
	for _, v := range res {
		res_json = append(res_json, dto.Dto_File(v))
	}
	if len(res) == 0 {
		response.Fail(ctx, http.StatusNotFound, nil, "文件列表为空")
	} else {
		response.Success(ctx, res_json, "获取成功")
	}
}

//需要更新的功能：删除图片、文件时的身份验证；删除数据库记录同时删除文件本体
